package com.anxin.aspect;

import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * 登录检查切面
 *
 * @author zengcheng
 * @date 2025/06/18
 */
@Aspect
@Component
public class LoginRequireAspect {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Around("@annotation(com.anxin.annotation.LoginRequire)")
    public Object checkLogin(ProceedingJoinPoint joinPoint) throws Throwable {
        //为了避免依赖 Controller 方法必须有 HttpServletRequest 参数，可以直接从 RequestContextHolder 中获取当前请求对象
        // 从 RequestContextHolder 获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            throw new RuntimeException("当前线程未绑定请求上下文");
        }
        HttpServletRequest request = attributes.getRequest();

        // 从请求头中获取 token
        String token = request.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            throw new RuntimeException("未登录");
        }

        token = token.substring(7); // 去掉 "Bearer " 前缀

        // 2. 从 Redis 获取用户信息
        String redisKey = "user:auth:" + token;
        Object userObj = redisTemplate.opsForValue().get(redisKey);
        if (userObj == null) {
            throw new RuntimeException("登录已过期，请重新登录");
        }

        // 3. 放行
        return joinPoint.proceed();
    }
}
